#include "TwoWayList.h"
#include "Record.h"
#include "Schema.h"
#include "File.h"
#include "Comparison.h"
#include "ComparisonEngine.h"
#include "DBFile.h"
#include "Defs.h"
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <strstream>
//testing svn
using namespace std;



DBFile::DBFile(){
	//genDBFile=NULL;
	//setOrder=NULL;
	//mySortInfo->myOrder=NULL;
	//mySortInfo->myOrder=new OrderMaker;
	//mySortInfo = new SortInfo;
	//mySortInfo=NULL;

}

DBFile::~DBFile(){
	//delete genDBFile;
	//delete setOrder;
	//delete mySortInfo;
	//mySortInfo->myOrder=NULL;
	//if(file_type=="sorted"){
delete mySortInfo->myOrder;

	//mySortInfo = NULL;
delete mySortInfo;

	//}

}

int DBFile::Create(char* f_path,fType f_type,void *startup){
	char temp[100];
	//delete it afterwards



	strcpy(temp,f_path);
	strcat(temp,".metadata");
	FILE* metaFile;
	/*=fopen(temp,"a+");
	fclose(metaFile);*/
	metaFile=freopen(temp,"w+",stdout);
	if(f_type==heap){
		genDBFile = new HeapDBFile;

		//Now make metadata file for the file opened
		printf("heap\n");

	}else if(f_type==sorted){
		mySortInfo = new SortInfo;
			mySortInfo->myOrder=new OrderMaker;


			mySortInfo= (struct SortInfo*)startup;
			genDBFile = new SortedDBFile(mySortInfo);
		//Now make metadata file for the file opened
		printf("sorted\n");
		printf("RunLength %d\n",mySortInfo->runLength);
		mySortInfo->myOrder->Print();


	}
	//fclose(stdout);
	//metaFile = fopen(temp,"r");

	fclose(metaFile);
	freopen ("/dev/tty", "w", stdout);
	//fopen(stdout);

	//fclose(metaFile);
	//delete temp;
	return genDBFile->Create(f_path);

}

//Function to open DBFile and get metadata from metadata file
int DBFile::Open(char* fpath){

	//Temporary variables
	char temp[100];
	//Delete this in end
	strcpy(temp,fpath);
	strcat(temp,".metadata");
	cout<<temp<<endl;


	//Initialization of ordermaker setting attributes
	string whichTypes[MAX_ANDS];
	int whichAtts[MAX_ANDS];
	int numAtts;
	int index;
	char orderData[100];
	char literal;
	char stringFromMetadata[100];

	//Parser to parse metadata file
	stringstream parser (stringstream::in|stringstream::out);
	int runLen;

	int i=0;
	ifstream metaFile(temp);
	if(metaFile.is_open())

	{
		getline(metaFile,file_type);
		if(file_type=="sorted")
		{
			//Fetching runlength
			metaFile.getline(orderData,20);
			parser<<orderData;
			parser>>stringFromMetadata>>runLen;
			cout<<"Run length "<<runLen<<endl;

			stringstream parser (stringstream::in|stringstream::out);
			//fetching number of atts
			metaFile.getline(orderData,20);
			cout<<"Line read : "<<orderData<<endl;

			parser<<orderData;
			parser>>stringFromMetadata>>literal>>numAtts;

			//cout<<stringFromMetada<<endl;
			cout<<"number of atts "<<numAtts<<endl;
			while(metaFile.good()&&i<numAtts)
			{

				stringstream parser (stringstream::in|stringstream::out);
				metaFile.getline(orderData,100);
				//if (orderData!= " ") {
				//cout<<"In while :: "<<orderData<<endl;
				parser<<orderData;
				parser>>index;
				parser>>literal>>whichAtts[index]>>whichTypes[index];
				//cout<<index<<literal<<" "<<whichAtts[index]<<" "<<whichTypes[index]<<endl;
				//}
				i++;
			}

			/*cout<<"Checking array"<<endl;
			for(i=0;i<numAtts;i++)
				cout<<i<<literal<<" "<<whichAtts[i]<<" "<<whichTypes[i]<<endl;*/
			mySortInfo = new SortInfo;
						mySortInfo->myOrder=new OrderMaker;


						//mySortInfo= (struct SortInfo*)startup;

			setOrder = new OrderMaker(numAtts,whichAtts,whichTypes);

			mySortInfo->myOrder=setOrder;
			mySortInfo->runLength=runLen;
			setOrder->Print();
			genDBFile = new SortedDBFile(mySortInfo);
		}
		else if(file_type=="heap")
		{
			genDBFile = new HeapDBFile;
		}

	}
	else
	{
		cout<<"cannot open the file"<<endl;
	}
	//delete temp;
	metaFile.close();
	return genDBFile->Open(fpath);

}

void DBFile::Load(Schema &myschema, char *loadpath){

}

//DBFile.add :: it calls addme from GenericDBFile object and checks at runtime whether heap or sorted version is called
void DBFile::Add(Record &addme){
	genDBFile->Add(addme);
}

void DBFile::MoveFirst(){
	genDBFile->MoveFirst();
}

int DBFile::GetNext(Record &fetchme){
	return genDBFile->GetNext(fetchme);

}

int DBFile::GetNext(Record &fetchme, CNF &cnf, Record &literal){
	return genDBFile->GetNext(fetchme,cnf,literal);

}

//Close the DBFile
int DBFile::Close(){
	return genDBFile->Close();

}
